﻿#include "protocolprocess.h"
#include <stdexcept>



ProtocolProcess::ProtocolProcess(QObject *parent) : QObject(parent)
{
    pReader = new QXmlStreamReader;

    pXmlFilePath = new QString;
}

ProtocolProcess::ProtocolProcess(QString file)
{
    pReader = new QXmlStreamReader;

    pXmlFilePath = new QString;

    readProtocol(file);
}

// 拷贝构造
ProtocolProcess::ProtocolProcess(ProtocolProcess& format) : QObject( nullptr )
{
    pReader = new QXmlStreamReader;

    pFormat_Settings = new struct _format_settings;

    pXmlFilePath = new QString;

    // 拷贝pReader
    if(format.getReader())
    {
        QFile newFormat(*format.getXmlFilePath());

        if (!newFormat.open(QFile::ReadOnly | QFile::Text))
        {
            if(format.getXmlFilePath()->length()>0)
                QMessageBox::warning(NULL, "警告", "格式文件"+*format.getXmlFilePath()+"打开失败!");
            else
                QMessageBox::warning(NULL, "警告", "格式文件路径为空!");
        }
        pReader->setDevice(&newFormat);
    }

    // 拷贝pFormat_Setting
    pFormat_Settings = format.getFormat_Settings();

    pXmlFilePath = format.getXmlFilePath();
}


bool ProtocolProcess::readProtocol(QString file)
{
    if(pFormat_Settings)
    {
        deleteFormatSetting();
    }
    pFormat_Settings = new struct _format_settings;

    if(false == isFileExist(file))
    {
        QMessageBox::warning(NULL, "警告", "格式文件\""+file+"\"读取失败!");
        return false;
    }

    QFile format(file);

    if (!format.open(QFile::ReadOnly | QFile::Text))
    {
        if(file.length()>0)
            QMessageBox::warning(NULL, "警告", "格式文件"+file+"打开失败!");
        else
            QMessageBox::warning(NULL, "警告", "格式文件路径为空!");
    }

    // 指定读取设备
    pReader->setDevice(&format);

    try {
        // 此处添加文档解析功能
        while(!pReader->atEnd())
        {
            pReader->readNext();

            if(pReader->isDTD())
            {
                continue;
            }

            // 解析Check_Infos标签
            if(pReader->name()==STRING_NODE_CHECK_INFOS && pReader->isStartElement())
            {
                pFormat_Settings->Check_Infos = new struct _check_infos;
                parseCheck_Infos();
            }

            // 解析Body标签
            if(pReader->name()==STRING_NODE_BODY   && pReader->isStartElement())
            {
                pFormat_Settings->Body = new struct _body;
                parseBody();
            }
        }
        // 任何1个节点解析不正确，排除异常
        if (NULL == pFormat_Settings->Check_Infos){
            throw QString("Check_Infos标签异常");
        }
        if (NULL == pFormat_Settings->Body) {
            throw QString("Body标签异常");
        }

    }
    catch (QString& error) {
        emit throwError(error);
        return false;
    }

    setXmlFilePath(file);
    return true;
}


// 解析Check_Infos标签
void ProtocolProcess::parseCheck_Infos()
{
    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Project标签
        if(pReader->name()==STRING_LABEL_CHECK_INFOS_PROJECT && pReader->isStartElement())
        {
            pFormat_Settings->Check_Infos->Project = new QString(pReader->readElementText());
        }

        // 解析Product标签
        if(pReader->name()==STRING_LABEL_CHECK_INFOS_PRODUCT && pReader->isStartElement())
        {
            pFormat_Settings->Check_Infos->Product = new QString(pReader->readElementText());
        }

        // 解析BaseLine标签
        if(pReader->name()==STRING_LABEL_CHECK_INFOS_BASELINE && pReader->isStartElement())
        {
            pFormat_Settings->Check_Infos->BaseLine = new QString(pReader->readElementText());
        }

        // 解析Date标签
        if(pReader->name()==STRING_LABEL_CHECK_INFOS_DATE && pReader->isStartElement())
        {
            pFormat_Settings->Check_Infos->Date = new QString(pReader->readElementText());
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_CHECK_INFOS && pReader->isEndElement())
        {
            break;
        }
    }

    // 异常处理
    // Project标签异常
    if(NULL == pFormat_Settings->Check_Infos->Project)
    {
        throw QString("Project标签异常");
        return;
    }

    // Product标签异常
    if(NULL == pFormat_Settings->Check_Infos->Product)
    {
        throw QString("Product标签异常");
        return;
    }

    // BaseLine标签异常
    if(NULL == pFormat_Settings->Check_Infos->BaseLine)
    {
        throw QString("BaseLine标签异常");
        return;
    }

    // Date标签异常
    if(NULL == pFormat_Settings->Check_Infos->Date)
    {
        throw QString("Date标签异常");
        return;
    }

    return;
}


// 解析Body标签
void ProtocolProcess::parseBody()
{

    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Enumerated标签
        if(pReader->name()==STRING_NODE_ENUMERATED && pReader->isStartElement())
        {
            if (NULL == pFormat_Settings->Body->Enumerated) {
                pFormat_Settings->Body->Enumerated = new QVector<struct _enumerated*>;
            }
            struct _enumerated* enumerated = new struct _enumerated;
            parseEnumerated(enumerated);
            pFormat_Settings->Body->Enumerated->append(enumerated);
        }

        // 解析Frame标签
        if(pReader->name()==STRING_NODE_FRAME && pReader->isStartElement())
        {
            pFormat_Settings->Body->Frame = new struct _frame;
            parseFrame();
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_BODY && pReader->isEndElement())
        {
            break;
        }
    }

    // 异常处理
    // Frame标签异常
    if(NULL == pFormat_Settings->Body->Frame)
    {
        throw QString("Frame标签异常");
        return;
    }

    return;
}


// 解析Enumerated标签
void ProtocolProcess::parseEnumerated(struct _enumerated* pEnumerated)
{

    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Label标签
        if(pReader->name()==STRING_LABEL_ENUMERATED_LABEL && pReader->isStartElement())
        {
            pEnumerated->Label = new QString(pReader->readElementText());
        }

        // 解析Value标签
        if(pReader->name()==STRING_NODE_VALUE && pReader->isStartElement())
        {
            if (NULL == pEnumerated->Value) pEnumerated->Value = new QVector<struct _value*>;
            struct _value* value = new struct _value;
            parseValue(value);
            pEnumerated->Value->append(value);
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_ENUMERATED && pReader->isEndElement())
        {
            break;
        }

    }

    return;
}


// 解析Value标签
void ProtocolProcess::parseValue(struct _value* pValue)
{
    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Code标签
        if(pReader->name()==STRING_LABEL_VALUE_CODE && pReader->isStartElement())
        {
            pValue->Code = new int(pReader->readElementText().toInt());
        }

        // 解析Label标签
        if(pReader->name()==STRING_LABEL_VALUE_LABEL && pReader->isStartElement())
        {
            pValue->Label = new QString(pReader->readElementText());
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_VALUE && pReader->isEndElement())
        {
            break;
        }
    }

    return;
}


// 解析Frame标签
void ProtocolProcess::parseFrame()
{

    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Endian标签
        if(pReader->name()==STRING_LABEL_FRAME_ENDIAN && pReader->isStartElement())
        {
            pFormat_Settings->Body->Frame->Endian = new QString(pReader->readElementText());
        }

        // 解析Field标签
        if(pReader->name()==STRING_NODE_FIELD && pReader->isStartElement())
        {
            if (NULL == pFormat_Settings->Body->Frame->Field) {
                pFormat_Settings->Body->Frame->Field = new QVector<struct _field*>;
            }
            struct _field* field = new struct _field;
            parseField(field);
            pFormat_Settings->Body->Frame->Field->append(field);
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_FRAME && pReader->isEndElement())
        {
            break;
        }
    }

    // 异常处理
    // Endian标签异常
    if (NULL == pFormat_Settings->Body->Frame->Endian) {
        throw QString("Endian标签异常");
        return;
    }

    // Field标签异常
    if (NULL == pFormat_Settings->Body->Frame->Field) {
        throw QString("Field标签异常");
        return;
    }

    return;
}


// 解析Field标签
void ProtocolProcess::parseField(struct _field* pField)
{
    // 将Display指针初始化为空，后续在解析数据时，如果该指针为空，则说明显示在工具栏中
    pField->Display = NULL;
    pField->Computation = NULL;
    pField->value = NULL;

    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Label标签
        if(pReader->name() == STRING_LABEL_FIELD_LABEL  && pReader->isStartElement())
        {
            pField->Label = new QString(pReader->readElementText());
        }

        // 解析Computation标签
        if(pReader->name() == STRING_NODE_COMPUTATION && pReader->isStartElement())
        {
            pField->Computation = new struct _computation;
            parseComputation(pField->Computation);
        }

        // 解析Display标签
        if(pReader->name() == STRING_NODE_DISPLAY && pReader->isStartElement())
        {
            pField->Display = new struct _display;
            parseDisplay(pField->Display);
        }

        // 退出解析
        if(pReader->name() == STRING_NODE_FIELD && pReader->isEndElement())
        {
            break;
        }

    }


    // 异常处理
    // Label标签异常
    if (NULL == pField->Label) {
        throw QString("Label标签异常");
        return;
    }


    return;
}


// 解析Computation标签
void ProtocolProcess::parseComputation(struct _computation* pComputation)
{
    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();


        // 解析Type标签
        if(pReader->name()== STRING_LABEL_COMPUTATION_TYPE && pReader->isStartElement())
        {
            pComputation->Type = new QString(pReader->readElementText());
        }

        // 解析First_Bit_Position标签
        if(pReader->name()== STRING_LABEL_COMPUTATION_FIRST_BIT_POSITION && pReader->isStartElement())
        {
            pComputation->First_Bit_Position = new unsigned int(pReader->readElementText().toUInt());
        }

        // 解析Bit_Count标签
        if(pReader->name()==STRING_LABEL_COMPUTATION_BIT_COUNT && pReader->isStartElement())
        {
            pComputation->Bit_Count = new unsigned int(pReader->readElementText().toUInt());
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_COMPUTATION && pReader->isEndElement())
        {
            break;
        }
    }

    // 异常处理
    // Type标签异常
    if (NULL == pComputation->Type) {
        throw QString("Computation节点下的Type标签异常");
        return;
    }
    // First_Bit_Position标签异常
    if (NULL == pComputation->First_Bit_Position) {
        throw QString("First_Bit_Position标签异常");
        return;
    }
    // Bit_Count标签异常
    if (NULL == pComputation->Bit_Count) {
        throw QString("Bit_Count标签异常");
        return;
    }

    return;
}

// 解析Display标签
void ProtocolProcess::parseDisplay(struct _display* pDisplay)
{
    // 初始化部分文件中的可选配置项
    pDisplay->Enumerated_Label = NULL;
    pDisplay->Decimal_Digits = NULL;
    pDisplay->Unit = NULL;
    pDisplay->Range = NULL;

    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();

        // 解析Type标签
        if(pReader->name()==STRING_LABEL_DISPLAY_TYPE && pReader->isStartElement())
        {
            pDisplay->Type = new QString(pReader->readElementText());
        }

        // 解析Enumerated_Label标签
        if(pReader->name()==STRING_LABEL_DISPLAY_ENUMERATED_LABEL && pReader->isStartElement())
        {
            pDisplay->Enumerated_Label = new QString(pReader->readElementText());
        }

        // 解析Decimal_Digits标签
        if(pReader->name()==STRING_LABEL_DISPLAY_DECIMAL_DIGITS && pReader->isStartElement())
        {
            pDisplay->Decimal_Digits = new unsigned int(pReader->readElementText().toUInt());
        }

        // 解析Unit标签
        if(pReader->name()==STRING_LABEL_DISPLAY_UNIT && pReader->isStartElement())
        {
            pDisplay->Unit = new QString(pReader->readElementText());
        }

        // 获取Page标签内容
        if(pReader->name()==STRING_NODE_POSITION && pReader->isStartElement())
        {
            pDisplay->Position = new struct _position;
            parsePosition(pDisplay->Position);
        }

        // 解析Range标签
        if(pReader->name()==STRING_NODE_RANGE && pReader->isStartElement())
        {
            pDisplay->Range = new struct _range;
            parseRange(pDisplay->Range);
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_DISPLAY && pReader->isEndElement())
        {
            break;
        }
    }

    // 异常处理
    // Type标签异常
    if (NULL == pDisplay->Type) {
        throw QString("Display节点下的Type标签异常");
        return;
    }
    return;
}


// 解析Position标签
void ProtocolProcess::parsePosition(struct _position* pPosition)
{
    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();
//        qDebug()<<"Position";
        // 解析Page标签
        if(pReader->name()==STRING_LABEL_POSITION_PAGE && pReader->isStartElement())
        {
            pPosition->Page = new unsigned int(pReader->readElementText().toUInt());
        }

        // 解析Line标签
        if(pReader->name()==STRING_LABEL_POSITION_ROW && pReader->isStartElement())
        {
            pPosition->Row = new unsigned int(pReader->readElementText().toUInt());
        }

        // 解析Col标签
        if(pReader->name()==STRING_LABEL_POSITION_COLUMN && pReader->isStartElement())
        {
            pPosition->Column = new unsigned int(pReader->readElementText().toUInt());
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_POSITION && pReader->isEndElement())
        {
            break;
        }
    }

    return;
}


// 解析Range标签
void ProtocolProcess::parseRange(struct _range* pRange)
{
    while(!pReader->atEnd())
    {
        // 读取下一个标签
        pReader->readNext();
//        qDebug()<<"Range";
        // 解析Minimum标签
        if(pReader->name()==STRING_LABEL_RANGE_MIN)
        {
            pRange->Min = new int(pReader->readElementText().toInt());
        }

        // 解析Maximum标签
        if(pReader->name()==STRING_LABEL_RANGE_MAX)
        {
            pRange->Max = new int(pReader->readElementText().toUInt());
        }

        // 退出解析
        if(pReader->name()==STRING_NODE_RANGE && pReader->isEndElement())
        {
            break;
        }
    }
    return;
}


// 获取Format_Settings属性
struct _format_settings* ProtocolProcess::getFormat_Settings()
{
    if(!pFormat_Settings)
    {
        return NULL;
    }
    return pFormat_Settings;
}


QXmlStreamReader* ProtocolProcess::getReader()
{
    return pReader;
}

void ProtocolProcess::setXmlFilePath(QString filePath)
{
    if (NULL == pXmlFilePath) pXmlFilePath = new QString;
    *pXmlFilePath = filePath;
    return;
}


QString* ProtocolProcess::getXmlFilePath()
{
    return pXmlFilePath;
}



void ProtocolProcess::deleteFormatSetting()
{
    if(pFormat_Settings)
    {
        if(pFormat_Settings->Check_Infos)
        {
            if(pFormat_Settings->Check_Infos->BaseLine)
            {
                delete pFormat_Settings->Check_Infos->BaseLine;
                pFormat_Settings->Check_Infos->BaseLine = NULL;
            }
            if(pFormat_Settings->Check_Infos->Date)
            {
                delete pFormat_Settings->Check_Infos->Date;
                pFormat_Settings->Check_Infos->Date = NULL;
            }
            if(pFormat_Settings->Check_Infos->Product)
            {
                delete pFormat_Settings->Check_Infos->Product;
                pFormat_Settings->Check_Infos->Product = NULL;
            }
            if(pFormat_Settings->Check_Infos->Project)
            {
                delete pFormat_Settings->Check_Infos->Project;
                pFormat_Settings->Check_Infos->Project = NULL;
            }
        }

        if(pFormat_Settings->Body)
        {
            if(pFormat_Settings->Body->Enumerated)
            {
                for (auto &item : std::as_const(*pFormat_Settings->Body->Enumerated)) {
                    if(item->Label)
                    {
                        delete item->Label;
                        item->Label = NULL;
                    }
                    if(item->Value)
                    {
                        delete item->Value;
                        item->Value = NULL;
                    }
                }
//                for(QVector<struct _enumerated*>::iterator it = pFormat_Settings->Body->Enumerated->begin(); it!=pFormat_Settings->Body->Enumerated->end(); ++it)
//                {
//                    if((*it)->Label)
//                    {
//                        delete (*it)->Label;
//                        (*it)->Label = NULL;
//                    }
//                    if((*it)->Value)
//                    {
//                        delete (*it)->Value;
//                        (*it)->Value = NULL;
//                    }
//                }
                delete pFormat_Settings->Body->Enumerated;
            }
            if(pFormat_Settings->Body->Frame)
            {
                for(auto &item : std::as_const(*pFormat_Settings->Body->Frame->Field))
                {
                    if(item->Label)
                    {
                        delete item->Label;
                        item->Label = NULL;
                    }

                    if(item->Computation)
                    {
                        if(item->Computation->Type)
                        {
                            delete item->Computation->Type;
                            item->Computation->Type = NULL;
                        }
                        if(item->Computation->First_Bit_Position)
                        {
                            delete item->Computation->First_Bit_Position;
                            item->Computation->First_Bit_Position = NULL;
                        }
                        if(item->Computation->Bit_Count)
                        {
                            delete item->Computation->Bit_Count;
                            item->Computation->Bit_Count = NULL;
                        }
                        delete item->Computation;
                        item->Computation = NULL;
                    }

                    if(item->Display)
                    {
                        if(item->Display->Type)
                        {
                            delete item->Display->Type;
                            item->Display->Type = NULL;
                        }
                        if(item->Display->Enumerated_Label)
                        {
                            delete item->Display->Enumerated_Label;
                            item->Display->Enumerated_Label = NULL;
                        }
                        if(item->Display->Decimal_Digits)
                        {
                            delete item->Display->Decimal_Digits;
                            item->Display->Decimal_Digits = NULL;
                        }
                        if(item->Display->Unit)
                        {
                            delete item->Display->Unit;
                            item->Display->Unit = NULL;
                        }
                        if(item->Display->Position)
                        {
                            if(item->Display->Position->Page)
                            {
                                delete item->Display->Position->Page;
                                item->Display->Position->Page = NULL;
                            }
                            if(item->Display->Position->Row)
                            {
                                delete item->Display->Position->Row;
                                item->Display->Position->Row = NULL;
                            }
                            if(item->Display->Position->Column)
                            {
                                delete item->Display->Position->Column;
                                item->Display->Position->Column = NULL;
                            }
                            delete item->Display->Unit;
                            item->Display->Unit = NULL;
                        }
                        if(item->Display->Range)
                        {
                            if(item->Display->Range->Max)
                            {
                                delete item->Display->Range->Max;
                                item->Display->Range->Max = NULL;
                            }
                            if(item->Display->Range->Min)
                            {
                                delete item->Display->Range->Min;
                                item->Display->Range->Min = NULL;
                            }
                            delete item->Display->Range;
                            item->Display->Range = NULL;
                        }
                    }

                    if(item->value)
                    {
                        delete item->value;
                        item->value = NULL;
                    }
                }
//                for(QVector<struct _field*>::iterator it = pFormat_Settings->Body->Frame->Field->begin(); it != pFormat_Settings->Body->Frame->Field->end(); ++it)
//                {
//                    if((*it)->Label)
//                    {
//                        delete (*it)->Label;
//                        (*it)->Label = NULL;
//                    }

//                    if((*it)->Computation)
//                    {
//                        if((*it)->Computation->Type)
//                        {
//                            delete (*it)->Computation->Type;
//                            (*it)->Computation->Type = NULL;
//                        }
//                        if((*it)->Computation->First_Bit_Position)
//                        {
//                            delete (*it)->Computation->First_Bit_Position;
//                            (*it)->Computation->First_Bit_Position = NULL;
//                        }
//                        if((*it)->Computation->Bit_Count)
//                        {
//                            delete (*it)->Computation->Bit_Count;
//                            (*it)->Computation->Bit_Count = NULL;
//                        }
//                        delete (*it)->Computation;
//                        (*it)->Computation = NULL;
//                    }

//                    if((*it)->Display)
//                    {
//                        if((*it)->Display->Type)
//                        {
//                            delete (*it)->Display->Type;
//                            (*it)->Display->Type = NULL;
//                        }
//                        if((*it)->Display->Enumerated_Label)
//                        {
//                            delete (*it)->Display->Enumerated_Label;
//                            (*it)->Display->Enumerated_Label = NULL;
//                        }
//                        if((*it)->Display->Decimal_Digits)
//                        {
//                            delete (*it)->Display->Decimal_Digits;
//                            (*it)->Display->Decimal_Digits = NULL;
//                        }
//                        if((*it)->Display->Unit)
//                        {
//                            delete (*it)->Display->Unit;
//                            (*it)->Display->Unit = NULL;
//                        }
//                        if((*it)->Display->Position)
//                        {
//                            if((*it)->Display->Position->Page)
//                            {
//                                delete (*it)->Display->Position->Page;
//                                (*it)->Display->Position->Page = NULL;
//                            }
//                            if((*it)->Display->Position->Row)
//                            {
//                                delete (*it)->Display->Position->Row;
//                                (*it)->Display->Position->Row = NULL;
//                            }
//                            if((*it)->Display->Position->Column)
//                            {
//                                delete (*it)->Display->Position->Column;
//                                (*it)->Display->Position->Column = NULL;
//                            }
//                            delete (*it)->Display->Unit;
//                            (*it)->Display->Unit = NULL;
//                        }
//                        if((*it)->Display->Range)
//                        {
//                            if((*it)->Display->Range->Max)
//                            {
//                                delete (*it)->Display->Range->Max;
//                                (*it)->Display->Range->Max = NULL;
//                            }
//                            if((*it)->Display->Range->Min)
//                            {
//                                delete (*it)->Display->Range->Min;
//                                (*it)->Display->Range->Min = NULL;
//                            }
//                            delete (*it)->Display->Range;
//                            (*it)->Display->Range = NULL;
//                        }
//                    }

//                    if((*it)->value)
//                    {
//                        delete (*it)->value;
//                        (*it)->value = NULL;
//                    }
//                }
            }
            delete pFormat_Settings->Body;
            pFormat_Settings->Body = NULL;
        }
        delete pFormat_Settings;
        pFormat_Settings = NULL;
    }

    return;
}

void ProtocolProcess::clearXmlFilePath()
{
    delete pXmlFilePath;
    pXmlFilePath = NULL;
    return;
}


ProtocolProcess::~ProtocolProcess()
{

    delete pReader;

    deleteFormatSetting();
}

